home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Sample Code / Snippets / Interapplication Communication / AE Interaction Sample ƒ / reciever.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  14.1 KB  |  411 lines  |  [TEXT/MPS ]

  1. /* Sender and Reciever are simple AppleEvent programs that demonstrate */
  2. /* all the permutations of interaction levels for sending */
  3. /* and recieving APpleEvents. */
  4. /* Have fun with them. */
  5. /* C.K. Haun */
  6. /* Apple DTS */
  7. /* this recieves the simple event */
  8. #include <Types.h>
  9. #include <memory.h>
  10. #include <Packages.h>
  11. #include <Errors.h>
  12. #include <quickdraw.h>
  13. #include <fonts.h>
  14. #include <dialogs.h>
  15. #include <windows.h>
  16. #include <menus.h>
  17. #include <events.h>
  18. #include <OSEvents.h>
  19. #include <Desk.h>
  20. #include <diskinit.h>
  21. #include <OSUtils.h>
  22. #include <resources.h>
  23. #include <toolutils.h>
  24. #include <AppleEvents.h>
  25. #include <EPPC.h>
  26. #include <GestaltEqu.h>
  27. #include <PPCToolbox.h> 
  28. #include <Processes.h>
  29. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  30.  
  31. void DrawMain(WindowPtr drawIt);
  32.  
  33. Boolean DoSelected(long val);
  34.  
  35. void InitAEStuff(void);
  36.  
  37. void DoHighLevel(EventRecord *AERecord);
  38. void DoDaCall(MenuHandle themenu, long theit);
  39. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  40.  
  41. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  42.  
  43. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  44.  
  45. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  46.  
  47. pascal OSErr AESimpleHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  48. pascal Boolean idleProc(EventRecord *eventIn, long *sleep, RgnHandle *mouseRgn);
  49. /* interaction menu items */
  50. #define kSelfInteractItem 1
  51. #define kLocalInteractItem 2
  52. #define kAllInteractItem 3
  53. short gInteractArray[4] = 
  54. {
  55.     nil, kAEInteractWithSelf, kAEInteractWithLocal, kAEInteractWithAll
  56. };
  57.  
  58.  
  59.  
  60.  
  61.  
  62. #define kMBarID 128
  63. #define kAppleMenu 128
  64. #define kFileMenu 129
  65. #define kEditMenu 130
  66. #define kToolsMenu 131
  67. #define kResumeMask             1       /* bit of message field for resume vs. suspend */
  68. MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle;
  69. Handle gMymenu;                                             /* my menu bar handle */
  70. struct AEinstalls {
  71.     AEEventClass theClass;
  72.     AEEventID theEvent;
  73.     EventHandlerProcPtr theProc;
  74. };
  75. typedef struct AEinstalls AEinstalls;
  76.  
  77. AEAddressDesc targetAddress;                                /* address of the person to get the data from */
  78.  
  79.  
  80. #define kSimpleEvent 'SIMP'
  81. #define kSimpleClass 'Simp'
  82. Boolean gQuit, gInBackground;
  83. EventRecord gERecord;
  84. WindowPtr myWindow;
  85. short gInteractNow = kSelfInteractItem;
  86. main()
  87. {
  88.     WindowPtr twindow;
  89.     MaxApplZone();
  90.     InitGraf((Ptr)&qd.thePort);
  91.     InitFonts();
  92.     InitWindows();
  93.     InitMenus();
  94.     TEInit();
  95.     InitDialogs(nil);
  96.     InitCursor();
  97.     
  98.     InitAEStuff();
  99.     
  100.     gMymenu = GetNewMBar(kMBarID);
  101.     SetMenuBar(gMymenu);
  102.     gAppleMenuHandle = GetMHandle(kAppleMenu);
  103.     gFileMenuHandle = GetMHandle(kFileMenu);
  104.     gEditMenuHandle = GetMHandle(kEditMenu);
  105.     gToolMenuHandle = GetMHandle(kToolsMenu);
  106.     
  107.     AddResMenu(gAppleMenuHandle, 'DRVR');
  108.     DrawMenuBar();
  109.     CheckItem(gToolMenuHandle, gInteractNow, true);
  110.     GetNewWindow(128, nil, (WindowPtr)-1);
  111.     
  112.     do {
  113.         WaitNextEvent(everyEvent, &gERecord, 30, nil);
  114.         switch (gERecord.what) {
  115.             
  116.             case nullEvent:
  117.                 /* no nul processing in this sample */
  118.                 break;
  119.             case updateEvt:
  120.                 DrawMain((WindowPtr)gERecord.message);      /* draw whatever window needs an update */
  121.                 break;
  122.             case mouseDown:
  123.                 /* first see where the hit was */
  124.                 switch (FindWindow(gERecord.where, &twindow)) {
  125.                     
  126.                     case inDesk:                            /* if they hit in desk, then the process manager */
  127.                         break;                              /* will switch us out, we don't need to do anything */
  128.                     case inMenuBar:
  129.                         DoSelected(MenuSelect(gERecord.where));
  130.                         break;
  131.                         
  132.                     case inSysWindow:
  133.                         /* pass to the system */
  134.                         SystemClick(&gERecord, twindow);
  135.                         break;
  136.                     case inContent:
  137.                         break;
  138.                     case inDrag:
  139.                         if (twindow == FrontWindow())
  140.                             DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
  141.                         break;
  142.                     case inGrow:
  143.                     case inGoAway:
  144.                         /* don't care */
  145.                         break;
  146.                         
  147.                 }
  148.             case mouseUp:
  149.                 /* don't care */
  150.                 break;
  151.                 /* same action for key or auto key */
  152.             case keyDown:
  153.             case autoKey:
  154.                 if (gERecord.modifiers & cmdKey)
  155.                     DoSelected(MenuKey(gERecord.message & charCodeMask));
  156.                 break;
  157.             case keyUp:
  158.                 /* don't care */
  159.                 break;
  160.             case diskEvt:
  161.                 /* I don't do anything special for disk events, this just passes them */
  162.                 /* to a function that checks for an error on the mount */
  163.                 DoDiskEvents(gERecord.message);
  164.                 break;
  165.             case activateEvt:
  166.                 /* Draws on a window activate.  Other activate/deactivate stuff is */
  167.                 /* handled in either the ChangePlane function (for normal shuffling ) */
  168.                 /* or in the suspend/resume handler for layer swaps */
  169.                 if (gERecord.modifiers & activeFlag)
  170.                     DrawMain((WindowPtr)gERecord.message);
  171.                 break;
  172.             case networkEvt:
  173.                 /* don't care */
  174.                 break;
  175.             case driverEvt:
  176.                 /* don't care */
  177.                 break;
  178.             case app4Evt:
  179.                 switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  180.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  181.                         gInBackground = (gERecord.message & kResumeMask) == 0;
  182.                         break;
  183.                 }
  184.                 break;
  185.             default:
  186.                 break;
  187.                 /* This dispatches high level events (AppleEvents, for example) */
  188.                 /* to our dispatch routine.  This is NEW in the event loop for */
  189.                 /* System 7 */
  190.             case kHighLevelEvent:
  191.                 DoHighLevel(&gERecord);
  192.                 break;
  193.                 
  194.         }
  195.     } while (gQuit != true);
  196.     
  197.     
  198. }
  199.  
  200. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  201. /* like to perform some action or just know when a DA is opened in your */
  202. /* layer.  Can be handy to track memory problems when a DA is opened */
  203. /* with an Option-open */
  204. void DoDaCall(MenuHandle themenu, long theit)
  205. {
  206.     long qq;
  207.     char DAname[255];
  208.     GetItem(themenu, theit, &DAname);
  209.     qq = OpenDeskAcc(DAname);
  210. }
  211.  
  212. /* end DoDaCall */
  213.  
  214. /* DoDiskEvents just checks the error code from the disk mount, */
  215. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  216. /* You can do much more here if you care about what disks are */
  217. /* in the drive */
  218. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  219. {
  220.     short hival, loval, tommy;
  221.     Point fredpoint =  {
  222.         40, 40
  223.     };
  224.     hival = HiWord(dinfo);
  225.     loval = LoWord(dinfo);
  226.     if (hival != noErr)                                     /* something happened */ {
  227.         tommy = DIBadMount(fredpoint, dinfo);
  228.     }
  229. }
  230.  
  231. void DrawMain(WindowPtr drawIt)
  232. {
  233.     BeginUpdate(drawIt);
  234.     SetPort(drawIt);
  235.     MoveTo(40, 70);
  236.     TextFace(bold);
  237.     TextSize(20);
  238.     DrawString("\pThis Does Nothing");
  239.     EndUpdate(drawIt);
  240. }
  241.  
  242. Boolean DoSelected(long val)
  243. {
  244.     short loval, hival;
  245.     Boolean temp = false;
  246.     short tempActionOut;
  247.     loval = LoWord(val);
  248.     hival = HiWord(val);
  249.     
  250.     switch (hival) {                                        /* switch off the menu number selected */
  251.         case kAppleMenu:                                    /* Apple menu */
  252.             if (loval != 1) {                               /* if this was not About, it's a DA */
  253.                 DoDaCall(gAppleMenuHandle, loval);
  254.             } else {
  255.                 Alert(128, nil);                            /* do about box */
  256.             }
  257.             break;
  258.         case kFileMenu:                                     /* File menu */
  259.             gQuit = true;                                   /* only edit item */
  260.             break;
  261.         case kEditMenu:
  262.             /* edit menu junk */
  263.             /* don't care */
  264.             break;
  265.         case kToolsMenu:
  266.             if (loval != gInteractNow) {
  267.                 CheckItem(gToolMenuHandle, gInteractNow, false);
  268.                 CheckItem(gToolMenuHandle, loval, true);
  269.                 AESetInteractionAllowed(gInteractArray[loval]);
  270.                 gInteractNow = loval;
  271.             }
  272.     }
  273.     HiliteMenu(0);
  274. }
  275.  
  276. void InitAEStuff(void)
  277. {
  278.     static AEinstalls HandlersToInstall[] =  {
  279.         {
  280.             kCoreEventClass, kAEOpenApplication, AEOpenHandler
  281.         },  {
  282.             kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
  283.         },  {
  284.             kCoreEventClass, kAEQuitApplication, AEQuitHandler
  285.         },  {
  286.             kCoreEventClass, kAEPrintDocuments, AEPrintHandler
  287.         }, 
  288.         /* The above are the four required AppleEvents. */ {
  289.             kSimpleClass, kSimpleEvent, AESimpleHandler
  290.         }
  291.     };
  292.     
  293.     OSErr aevtErr = noErr;
  294.     long aLong = 0;
  295.     Boolean gHasAppleEvents = false;
  296.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  297.     *   then we exit */
  298.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  299.     /* The following series of calls installs all our AppleEvent Handlers.
  300.     *   These handlers are added to the application event handler list that 
  301.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  302.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  303.     *   list of handlers and dispatch to it if there is one.
  304.     */
  305.     if (gHasAppleEvents) {
  306.         register qq;
  307.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  308.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  309.                                             HandlersToInstall[qq].theProc, 0, false);
  310.             if (aevtErr) {
  311.                 ExitToShell();                              /* just fail, baby */
  312.             }
  313.         }
  314.     } else {
  315.         ExitToShell();
  316.     }
  317. }
  318.  
  319. /* end InitAEStuff */
  320.  
  321. void DoHighLevel(EventRecord *AERecord)
  322. {
  323.     
  324.     AEProcessAppleEvent(AERecord);
  325.     
  326. }
  327.  
  328. /* end DoHighLevel */
  329.  
  330. /* This is the standard Open Application event.  You'll get this as one of the (if not the ) */
  331. /* first events in your application.  So, we open up a blank document */
  332. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  333. {
  334. #pragma unused (messagein,reply,refIn)
  335.     /* we of course don't do anything here, since we're background only */
  336.     return(noErr);
  337. }
  338.  
  339. /* end AEOpenHandler */
  340.  
  341. /* Open Doc, opens our documents.  Remember, this can happen at application start AND */
  342. /* anytime else.  If your app is up and running and the user goes to the desktop, hilites one */
  343. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  344. /* handler will get called. Which means you don't do any initialization of globals here, or */
  345. /* anything else except open then doc.  */
  346. /* SO-- Do NOT assume that you are at app start time in this */
  347. /* routine, or bad things will surely happen to you. */
  348.  
  349. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  350. {
  351. #pragma unused (reply, refIn)
  352.     /* we of course don't do anything here */
  353.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  354.     
  355. }
  356.  
  357. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  358. {                                                           /* no printing handler in yet, so we'll ignore this */
  359.     /* the operation is functionally identical to the ODOC event, with the additon */
  360.     /* of calling your print routine.  */
  361. #pragma unused (reply,refIn)
  362.     /* we of course don't do anything here */
  363.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  364. }
  365.  
  366. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  367. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  368. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  369. {
  370. #pragma unused (messagein,refIn)
  371.     
  372.     /* prepQuit sets the Stop flag for us.  It does _NOT_ quit, you */
  373.     /* should NEVER quit from an AppleEvent handler.  Calling */
  374.     /* ExitToShell here would blow things up */
  375.     gQuit = true;
  376.     return(noErr);
  377. }
  378.  
  379. pascal OSErr AESimpleHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  380. {
  381.     OSErr myErr = AEInteractWithUser(kAEDefaultTimeout, nil, (IdleProcPtr)idleProc);
  382.     if (myErr != errAENoUserInteraction)
  383.         Alert(444, nil);
  384.     return(noErr);
  385. }
  386.  
  387. pascal Boolean idleProc(EventRecord *eventIn, long *sleep, RgnHandle *mouseRgn)
  388. {
  389.     switch (eventIn->what) {
  390.         case nullEvent:
  391.             /* no nul processing in this sample */
  392.             *sleep = 0;
  393.             mouseRgn = nil;
  394.             break;
  395.         case updateEvt:
  396.         case activateEvt:
  397.             DrawMain((WindowPtr)eventIn->message);          /* draw whatever window needs an update */
  398.             break;
  399.         case app4Evt:
  400.             switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  401.                 case suspendResumeMessage:                  /* suspend/resume is also an activate/deactivate */
  402.                     gInBackground = (gERecord.message & kResumeMask) == 0;
  403.                     break;
  404.             }
  405.             break;
  406.             
  407.             
  408.     }
  409.     return(false);                                          /* I'll wait forever */
  410. }
  411.